package com.wolfman.uploadfile.controller;

import com.wolfman.uploadfile.components.RedisComponent;
import com.wolfman.uploadfile.components.UploadFileComponent;
import com.wolfman.uploadfile.po.FileUpload;
import com.wolfman.uploadfile.service.FileUploadService;
import com.wolfman.uploadfile.vo.FileVo;
import com.wolfman.uploadfile.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @Title
 * @Description
 * @Author WolfMan
 * @Date 2021/8/22 19:18
 * @Email 2370032534@qq.com
 */
@Slf4j
@RestController
@RequestMapping("/upload")
public class UploadFileController {
    /**
     * 文件相关组件
     */
    @Resource
    UploadFileComponent uploadFileComponent;
    /**
     * 文件上传业务接口
     */
    @Resource
    FileUploadService fileUploadService;
    /**
     * redis工具
     */
    @Resource
    RedisComponent redisComponent;

    /**
     * 获取文件上传id
     *
     * @return
     */
    @GetMapping("/getUploadId")
    public Result getUploadId(@RequestParam("filename") String uploadFilename) {
        //生成文件名
        String filename = uploadFileComponent.generateFilename(uploadFilename);
        File f = new File(new File("").getAbsolutePath() + "/src/main/resources/static/images/");
        if (!f.exists()) {
            f.mkdirs();
        }
        //调用service存储文件基本信息
        FileUpload fileUpload = new FileUpload();
        fileUpload.setFilename(filename);
        fileUpload.setFilePath("/images/" + filename);
        fileUpload.setUploadProgress(0D);
        fileUploadService.insertOne(fileUpload);
        return Result.success(fileUpload, "成功获取!");
    }


    /**
     * 上传单个文件
     *
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @PostMapping("/uploadFile")
    public Result uploadFile(FileVo fileVo) throws Exception {
        log.info("正在上传：{}", fileVo);
        //判断文件是否为空
        if (fileVo.getFile().isEmpty()) {
            return Result.error("上传失败！未选择文件！");
        }
        //查找fileUpload
        FileUpload fileUpload = new FileUpload();
        fileUpload.setId(fileVo.getUploadId());
        FileUpload f = fileUploadService.selectById(fileUpload);
        if (f == null) {
            return Result.error("");
        }
        String filePath = new File("").getAbsolutePath() + "/src/main/resources/static" + f.getFilePath();
        //上传文件
        uploadFileComponent.randomAccessUploadFile(fileVo, filePath, fileUpload, fileVo.getStart());
        //返回对应的文件上传信息
        return Result.success(fileUpload, "正在上传！");
    }

    /**
     * 获取实时长传进度
     *
     * @return
     */
    @GetMapping("/getPercent")
    public Result getPercent(FileUpload fileUpload) {
        Double percent = (Double) redisComponent.get("id:" + fileUpload.getId() + "-percent:");
        if (percent == null) {
            percent = 0D;
        }
        return Result.success(String.format("%.2f", percent), "请求成功！");
    }

    /**
     * 暂停文件上传
     *
     * @return
     */
    @GetMapping("/pauseUpload")
    public Result pauseUpload(FileUpload fileUpload) {
        redisComponent.set("id:" + fileUpload.getId() + "-isPause", true);
        return Result.success(null, "暂停成功！");
    }

    /**
     * 继续文件上传
     *
     * @return
     */
    @GetMapping("/continueUpload")
    public Result continueUpload(FileUpload fileUpload) throws Exception {
        //获取文件
        FileUpload f = fileUploadService.selectById(fileUpload);
        //获取文件绝对路径
        String filePath = new File("").getAbsolutePath() + "/src/main/resources/static/images/" + f.getFilename();
        //获取偏移量
        long available = new FileInputStream(filePath).available();
        //通过随机流上传
        return Result.success(available, "继续上传！");
    }

    /**
     * 取消文件上传
     *
     * @return
     */
    @GetMapping("/cancelUpload")
    public Result cancelUpload(FileUpload fileUpload) {
        //停止文件流
        pauseUpload(fileUpload);
        //获取文件
        FileUpload f = fileUploadService.selectById(fileUpload);
        //删除文件
        File file = new File(new File("").getAbsolutePath() + "/src/main/resources/static" + f.getFilePath());
        boolean delete = file.delete();
        while (!delete) {
            delete = file.delete();
        }
        log.info("成功删除文件：{}", file.getAbsolutePath());
        //删除redis相关信息
        redisComponent.del("id:" + f.getId() + "-isPause");
        redisComponent.del("id:" + f.getId() + "-percent:");
        //删除数据库中记录
        fileUploadService.deleteById(f);
        return Result.success(null, "取消成功！");
    }
}
